#include "./include/minishellBase.h"
#include "./include/builtinFunctions.h"

// external variables about the length of the builtin function list
extern size_t fcnList_len;
int main(){
	if(!initialize()){
		perror("initialize failed");
		return 1;
	}
	
	PROMPT_TYPE * selfDef_types;
	selfDef_types = (PROMPT_TYPE *) calloc(PROMPT_NUMBER,sizeof(PROMPT_TYPE));
	// selfDef_types = (PROMPT_TYPE *) calloc(fcnList_len, sizeof(PROMPT_TYPE));
	load_fcnList(selfDef_types);
	
 	char *input_str = NULL;
	PARSER *cmd = NULL;

	char * path2exe = NULL;

	if((path2exe = get_self_path()) == NULL){
		Print_errorInfo("$ Error:\n\tFail to get the path of the current executable file\n",__FILE__,__LINE__);
	}else{
		while(1){
			cmd = calloc(1,sizeof(PARSER));
			// input_str = (char *)calloc(MAX_PROMPT_LENGTH,sizeof(char));

			if((input_str = Input_string())== NULL) break;
			Clear_space(&input_str,strlen(input_str));
			if(strlen(input_str) < 1){
				Print_current_workpath(); printf(">> ");
				continue;
			}else if(strcmp(input_str,"quit") == 0){
				break;
			}

			if(!Identify_promptType(input_str,selfDef_types,fcnList_len, cmd)){ // identify the prompt type (is it a builtin command or an external command)
				// execute the builtin command in child process
				executeExternCMD(input_str, path2exe);
			} else{
				// execute the builtin command
				cmd = (cmd->selfDef_type->fcn_ptr)(cmd);

				printf("@cmd: %s\n",cmd->cmd_string);
				for(int i = 0; i < (int)cmd->para_num; i++){
					printf("@para: %s\n",cmd->parameters[i]);
				}
			}
			
			Print_current_workpath(); printf(">> ");

			// free the data structure of cmd and input_str
			free(input_str); input_str = NULL;
			Free_parser(&cmd); 
		}
	}

	// (*selfDef_type[index].func_ptr)("\n\n-----\n%s\n",selfDef_type[index].parameters[0]);
	free(input_str); input_str = NULL;
	Free_parser(&cmd);
	Free_promptTypeList(&selfDef_types,fcnList_len);
	
	return 0;
}

